package com.cius.util.hibernate;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 *自定义Hibernate映射类型
 * Created by CiusCheung on 16/9/18.
 */
public class EnumType<T extends Enum<T>> implements UserType {

    //生成的数据库数据类型
    private static final int[] SQl_TYPES = {Types.VARCHAR};
    private Class<T> clazz = null;

    //构造方法
    public EnumType(Class<T> c){
        this.clazz = c;
    }

    @Override
    public int[] sqlTypes() {
        return SQl_TYPES;
    }

    @Override
    public Class<T> returnedClass() {
        return clazz;
    }

    @Override
    public boolean equals(Object o, Object o1) throws HibernateException {
        if(o == o1){
            return true;
        }
        if(null == o || null == o1){
            return true;
        }
        return o.equals(o1);
    }

    @Override
    public int hashCode(Object o) throws HibernateException {
        return o.hashCode();
    }

    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] strings, SessionImplementor sessionImplementor, Object o) throws HibernateException, SQLException {
        try{
            //获取字段值
            String name = resultSet.getString(strings[0].toUpperCase());
            //将字段值转换成枚举
            return Enum.valueOf(clazz,name);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i, SessionImplementor sessionImplementor) throws HibernateException, SQLException {
        if(null == o){
            preparedStatement.setNull(i,Types.VARCHAR);
        }else{
            //将枚举转换成字符串
            preparedStatement.setString(i,((Enum)o).name());
        }
    }

    @Override
    public Object deepCopy(Object o) throws HibernateException {
        return o;
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Serializable disassemble(Object o) throws HibernateException {
        return (Serializable) o;
    }

    @Override
    public Object assemble(Serializable serializable, Object o) throws HibernateException {
        return serializable;
    }

    @Override
    public Object replace(Object o, Object o1, Object o2) throws HibernateException {
        return o;
    }
}
